package com.qingcloud.df.executor.process.kube;

import com.qingcloud.df.executor.pojo.process.config.AllowedHosts;
import com.qingcloud.df.executor.pojo.process.config.ResourceRequirements;
import com.qingcloud.df.executor.process.ProcessFactory;
import com.qingcloud.df.sdk.component.context.CompInstContext;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.HashMap;
import java.util.Map;

public class K8sProcessFactory implements ProcessFactory {
    private static final Logger logger = LoggerFactory.getLogger(K8sProcessFactory.class);

    @Override
    public Process bulidProcess(String imageName,
                                String suffix,
                                String rootPath,
                                String componentNameEn,
                                Map<String, String> files,
                                String entrypoint,
                                ResourceRequirements resourceRequirements,
                                AllowedHosts allowedHosts,
                                String... args) throws Exception {

        try {
//            String type = String.valueOf(context.getType());
//            Integer jobId = context.getJobId();
//            String instacneId = String.valueOf(context.getId());
            final Map<String, String> customLabels= null;
            final int attempt = 0 ;
            // used to differentiate source and destination processes with the same id and attempt
            final String podName = ProcessFactory.createProcessName(imageName, suffix, DOCKER_NAME_LEN_LIMIT);
            logger.info("Attempting to start pod = {} for {} with resources {} and allowedHosts {}", podName, imageName, resourceRequirements,
                    allowedHosts);

            final int stdoutLocalPort = KubePortManagerSingleton.getInstance().take();
            logger.info("{} stdoutLocalPort = {}", podName, stdoutLocalPort);

            final int stderrLocalPort = KubePortManagerSingleton.getInstance().take();
            logger.info("{} stderrLocalPort = {}", podName, stderrLocalPort);

//            final var allLabels = getLabels(String.valueOf(jobId), attempt, customLabels);

            // If using isolated pool, check workerConfigs has isolated pool set. If not set, fall back to use
            // regular node pool.

            //////////////TODO
//            final var nodeSelectors = null;
//
//            return new KubePodProcess(
//                    isOrchestrator,
//                    processRunnerHost,
//                    fabricClient,
//                    podName,
//                    namespace,
//                    imageName,
//                    workerConfigs.getJobImagePullPolicy(),
//                    workerConfigs.getSidecarImagePullPolicy(),
//                    stdoutLocalPort,
//                    stderrLocalPort,
//                    kubeHeartbeatUrl,
//                    usesStdin,
//                    files,
//                    entrypoint,
//                    resourceRequirements,
//                    workerConfigs.getJobImagePullSecrets(),
//                    workerConfigs.getWorkerKubeTolerations(),
//                    nodeSelectors,
//                    allLabels,
//                    workerConfigs.getWorkerKubeAnnotations(),
//                    workerConfigs.getJobSocatImage(),
//                    workerConfigs.getJobBusyboxImage(),
//                    workerConfigs.getJobCurlImage(),
//                    MoreMaps.merge(jobMetadata, workerConfigs.getEnvMap()),
//                    internalToExternalPorts,
//                    args).toProcess();
        } catch (final Exception e) {
            throw new Exception(e.getMessage(), e);
        }
        return null;
    }

    @Override
    public void processStop(String imageName ,String suffix) {

    }

    public static Map<String, String> getLabels(final String jobId, final int attemptId, final Map<String, String> customLabels) {
        final var allLabels = new HashMap<>(customLabels);

        final var generalKubeLabels = Map.of(
                Metadata.JOB_LABEL_KEY, jobId,
                Metadata.ATTEMPT_LABEL_KEY, String.valueOf(attemptId),
                Metadata.WORKER_POD_LABEL_KEY, Metadata.WORKER_POD_LABEL_VALUE);

        allLabels.putAll(generalKubeLabels);

        return allLabels;
    }
}
